﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Contract;
using System.Data.SqlClient;
using System.Data;
using System.ServiceModel;




namespace Service
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    class DataUploader : IDataUploader
    {
        SqlConnection con = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\P.Wu\\Desktop\\FileSharing 7.6\\service\\Database1.mdf;Integrated Security=True;User Instance=True");

        public void Upload(MyFile Mf)
        {
            string ServerPath = Path.Combine("Storage", Mf.Name);
            using (FileStream fs = new FileStream(ServerPath, FileMode.Create))
            {
                int bufferSize = 1 * 1024 * 1024; // 1 MB buffer
                byte[] buffer = new byte[bufferSize];
                int bytes;

                while ((bytes = Mf.Value.Read(buffer, 0, bufferSize)) > 0)
                {
                    fs.Write(buffer, 0, bytes);
                    fs.Flush();
                }
            }

            filetable(Mf.Name, Mf.PCN);
            callbackRefreshFileList();
        }
        public void filetable(string fileName, string PCN)
        {
            SqlCommand SqlCom = new SqlCommand();
            con.Open();

            SqlCom = con.CreateCommand();
            var timeNow = DateTime.Now;

            string Property = "Private";
            string FileID = PCN + timeNow;
            SqlCom.Parameters.Add("@paramPCN", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramFileID", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramFileName", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramFileTime", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramProperty", SqlDbType.VarChar);
            SqlCom.Parameters["@paramPCN"].Value = PCN;
            SqlCom.Parameters["@paramFileID"].Value = FileID;
            SqlCom.Parameters["@paramFileName"].Value = fileName;
            SqlCom.Parameters["@paramFileTime"].Value = timeNow;
            SqlCom.Parameters["@paramProperty"].Value = Property;
            SqlCom.CommandText = @"INSERT INTO [File] (FileID, FileName, FileOwnerPCN, FileUploadTime, Property) VALUES (@paramFileID,@paramFileName,@paramPCN,@paramFileTime,@paramProperty)";

            SqlCom.ExecuteNonQuery();





            con.Close();
        }


        public Stream Download(string name)
        {
            string fPath = Path.Combine("Storage", name);

            if (!File.Exists(fPath))
                throw new FileNotFoundException("File was not found", Path.GetFileName(fPath));

            return new FileStream(fPath, FileMode.Open, FileAccess.Read);
            // return ReadFully(fs);

        }


        public void Delete(string name)
        {
            string serverPath = Path.Combine("Storage", name);

            if (File.Exists(serverPath))
            {
                File.Delete(serverPath);

            }

        }

        public MyFile[] Getfilesinfo(string filesPath)
        {

            string BasePath = "Storage";
            if (!string.IsNullOrEmpty(filesPath))
                BasePath = Path.Combine("Storage", filesPath);
            DirectoryInfo dirInfo = new DirectoryInfo(BasePath);
            FileInfo[] files = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);

            return (from f in files
                    select new MyFile()
                    {
                        Name = f.Name,
                        Size = f.Length,
                        Value = null
                    }).ToArray();
        }

        public static byte[] ReadFully(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        public bool Login(string PCN, string Password)
        {

            con.Open();



            string cmdStr = "select * from [User] where PCN ='" + PCN + "' and Password ='" + Password + "' and Property = 'active'";
            SqlCommand sqlCom = new SqlCommand(cmdStr, con);


            if (sqlCom.ExecuteScalar() != null)
            {
                con.Close();
                return true;
            }


            else
            {
                con.Close();
                return false;
            }

        }
        public int Register(string Email, string Password, string Fname, string Lname, string Gender)
        {

            //bool success = true;
            Random r = new Random();
            int RandomPCN = r.Next(10000000, 99999999);

            // string cmdStr = "INSERT INTO [User] (PCN, Password, Email, Fname, Lname,Gender) values('" + RandomPCN + "','" +Password + "','" +Email + "','" + Fname + "','" + Lname + "','" + Gender + "')";


            SqlCommand SqlCom = new SqlCommand();
            con.Open();

            SqlCom = con.CreateCommand();

            string Property = "active";
            SqlCom.Parameters.Add("@paramPCN", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramPassword", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramEmail", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramFname", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramLname", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramGender", SqlDbType.VarChar);
            SqlCom.Parameters.Add("@paramProperty", SqlDbType.VarChar);
            SqlCom.Parameters["@paramPCN"].Value = RandomPCN;
            SqlCom.Parameters["@paramPassword"].Value = Password;
            SqlCom.Parameters["@paramEmail"].Value = Email;
            SqlCom.Parameters["@paramFname"].Value = Fname;
            SqlCom.Parameters["@paramLname"].Value = Lname;
            SqlCom.Parameters["@paramGender"].Value = Gender;
            SqlCom.Parameters["@paramProperty"].Value = Property;
            SqlCom.CommandText = @"INSERT INTO [User] (PCN, Password, Email, Fname, Lname,Gender, Property) VALUES (@paramPCN,@paramPassword,@paramEmail,@paramFname,@paramLname,@paramGender,@paramProperty)";

            SqlCom.ExecuteNonQuery();





            con.Close();
            return RandomPCN;




        }



        private void callbackRefreshFileList()
        {
            NetTcpBinding binding = new NetTcpBinding();
            binding.TransferMode = TransferMode.Buffered;
            binding.SendTimeout = TimeSpan.MaxValue;
            binding.MaxReceivedMessageSize = 100000000;
            binding.PortSharingEnabled = true;

            EndpointAddress address = new EndpointAddress("net.tcp://127.0.0.1:8001/CallBack");

            ChannelFactory<ICallBack> channel = new ChannelFactory<ICallBack>(binding, address);
            ICallBack Proxy = channel.CreateChannel();
            Proxy.CallBackPushFileList(Getfilesinfo(null));//Return the complete list of file. Need to be change later on.
        }

        public MyFile[] test1()
        {
            con.Open();

            int a = 1;

            string cmdStr = "select * from [User] where PCN ='"+a+"' ";
            SqlCommand sqlCom = new SqlCommand(cmdStr, con);
            SqlDataReader queryCommandReader = sqlCom.ExecuteReader();

            // Create a DataTable object to hold all the data returned by the query.
            DataTable dataTable = new DataTable();

            // Use the DataTable.Load(SqlDataReader) function to put the results of the query into a DataTable.
            dataTable.Load(queryCommandReader);
            MyFile[] f = {new MyFile()};
            // Example 1 - Print your  Column Headers
            String columns = string.Empty;
            foreach (DataColumn column in dataTable.Columns)
            {
                columns += column.ColumnName + " | ";
            }
           // Console.WriteLine(columns);
            f[0].Name=columns;

            // Example 2 - Print the first 10 row of data
            int topRows = 1;
            for (int i = 0; i < topRows; i++)
            {
                String rowText = string.Empty;
                foreach (DataColumn column in dataTable.Columns)
                {
                    rowText += dataTable.Rows[i][column.ColumnName] + " | ";
                }
                //Console.WriteLine(rowText);
                f[0].PCN = rowText;
            }
            
            
            

            sqlCom.ExecuteScalar();

            con.Close();
            return f;

        }
    }
}
    

